//
// Created by Ivor_ on 2023/11/28.
//

#ifndef PHYSICAL_COMPUTING_PACKAGE_RANDOMBITS_H
#define PHYSICAL_COMPUTING_PACKAGE_RANDOMBITS_H

#include <stdlib.h>

/**
 * @author Ivor
 * @param newSeed change to the new seed directly and warm the generator up
 * @return the new seed or the random value between [0, 5084753) / [0.0, 1.0)
 */
static unsigned long long int seedForLCG = 123456789llu;

unsigned long long int sRand_LCG(unsigned long long int newSeed);
unsigned long long int rand_LCG();
double rand_LCGD();

struct randomLCG {
    unsigned long long int currentSeed;
    unsigned long long int (*srand)(unsigned long long int);
    unsigned long long int (*randi)();
    double (*randf)();
};

struct randomLCG rlcg(void);

/**
 * @author Ivor
 * @param newSeed change to the new seed directly and warm the generator up
 * @return the new seed or the random value between [0, 4294967296) / [0.0, 1.0)
 */
static unsigned long long int seedForMWC = 13579llu;

unsigned long long int sRand_MWC(unsigned long long int newSeed);
unsigned long long int rand_MWC();
double rand_MWCD();

struct randomMWC {
    unsigned long long int currentSeed;
    unsigned long long int (*srand)(unsigned long long int);
    unsigned long long int (*randi)();
    double (*randf)();
};

struct randomMWC rmwc(void);

/**
 * @author Ivor
 * @param newSeed change to the new seed directly and warm the generator up
 * @return the new seed or the random value between [0, 4294967296) / [0.0, 1.0)
 */
static unsigned long long int seedForXorShift = 88675123llu;

unsigned long long int sRand_XorShift(unsigned long long int newSeed);
unsigned long long int rand_XorShift();
double rand_XorShiftD();

struct randomXorShift {
    unsigned long long int currentSeed;
    unsigned long long int (*srand)(unsigned long long int);
    unsigned long long int (*randi)();
    double (*randf)();
};

struct randomXorShift rXorS(void);

#endif //PHYSICAL_COMPUTING_PACKAGE_RANDOMBITS_H
